#include "json.h"
#include "AbstractFactory.h"
#include "ClassObjectPool.h"

#include <iostream>
#include <fstream>
#include <gtest/gtest.h>
#include <string>

using namespace std;


TEST(Json, readFileAnd2Json) {
}

class Wind {
public:
    virtual ~Wind() {}
    virtual void click(const int x, const int y) = 0;
};

class Button: public Wind {
public:
    Button(Json::Value& config) {
        cout << "Button config: " << config.toStyledString() << endl;
    }

    ~Button() {
        cout << "~Button" << endl;
    }

    void click(const int x, const int y) {
        cout << "Button click x: " << x << " y: " << y << endl;
    }

};

class Text: public Wind {
public:
    Text(Json::Value& config)
    {
        cout << "Text config: " << config.toStyledString() << endl;
    }

    void click(const int x, const int y) {
        cout << "Text click x: " << x << " y: " << y << endl;
    }

    ~Text()
    {
        cout << "~Text" << endl;
    }
    
};

//NOTE 1.首先， RegisterFactory是由GUI展示库负责注册的
TEST(Json, RegisterFactory) {
    AbstractFactory::RegisterBase<Wind, Button, Json::Value&>("Button");
    AbstractFactory::RegisterBase<Wind, Text, Json::Value&>("Text");
}

//NOTE 2. 其次， Json2Obj是将json读取并完成GUI对象生成和注册到对象池中的,Json2Obj的代码应该是标准且固定不变的
TEST(Json, Json2Obj) {
    //1. 读取配置文件转为json对象
    Json::Value GlobalCustomeCfg = Json::nullValue;
    std::ifstream ifs;
    ifs.open("../Test/jsonFile.json", std::ios::in);
    if(!ifs.is_open()) {
        return ;
    }
    std::string content;
    while(!ifs.eof()) {
        std::string str;
        ifs >> str;
        content += str;
    }
    ifs.close();
    Json::Reader jsonReader;
    jsonReader.parse(content, GlobalCustomeCfg);
    std::cout << GlobalCustomeCfg.toStyledString() << std::endl;
    //2. 解析json对象: 1. 依据json生成对象，2.将生成的对象insert到对象池中
    Json::Value::Members mem = GlobalCustomeCfg.getMemberNames();
    for(auto iter = mem.begin(); iter != mem.end(); ++iter) {
        ClassObjectPool obj;
        obj.Insert( (*iter), AbstractFactory::getObject<Wind, Json::Value&>(GlobalCustomeCfg[*iter]["property"].asString(), GlobalCustomeCfg[*iter]));
    }

}

//NOTE 3. GUI应用层代码
TEST(Json, GetJsonObj) {
     ClassObjectPool obj;
     std::string objectName = "TestButton1";
     shared_ptr<Wind> ptr = obj.Get<Wind>(objectName);
     ptr->click(1, 2);
}
